from functools import wraps

def outer(func):
    @wraps(func)
    def wrapper(*args,**kwargs): #装饰后的方法
        print("before func")
        wrapper_result=func(*args,**kwargs)
        print("after func")
        return wrapper_result
    return wrapper

def outer_args(input_args):
    def outer(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print(input_args)
            wrapper_result = func(*args, **kwargs)
            print("end")
            return wrapper_result
        return wrapper
    return outer


class outer_cls():
    #def __init__(self, func):
        #self.__func = func

    def __call__(self, *args, **kwargs):

        #self.input_args = input_args
        print("Start")
        res = self.__func(*args, **kwargs)
        print("End")
        return res

    def outer(self, *args, **kwargs):
        print("Start")
        print(*args)
        print(*kwargs)
        def inner_func(func):
            print("get func")
            @wraps(func)
            def wrapper(*args, **kwargs):
                res = func(*args, **kwargs)
                return res
            return wrapper
        return inner_func
        #res = self.__func(*args, **kwargs)
        #print("End")
        #return res

outerObj = outer_cls()


# 这种装饰器相当于是三层
#第一层进入函数outer  先把参数 Foo_table传进去
#第二层  进入第一层函数返回的函数中   把函数foo作为参数传进去
#第三层 进入第二层返回的函数中 把参数 a,  b 传进去

#@outerObj.outer("Foo_table")
#def foo(a,b):
#    return a+b


#############################################################################


def date_deco(func):
    def get_date_args(*args, **kwargs):
        print("before date")
        print(*args)
        res = func(*args, **kwargs)
        print("after date")
        return res
    return get_date_args

@date_deco
def date(boy, girl):
    print("{} and {} are having a date".format(boy, girl))
    return True


if __name__ == "__main__":
    #print( foo(2, 4))
    print(date("lilei", "hanmeimei"))

    #print(foo(555, 999))


    #print(foo.__name__)